package fr.loof.fonzie.parsers;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import fr.loof.fonzie.PersistenceQuery;
import fr.loof.fonzie.keywords.Aggregate;

/**
 * @author <a href="nicolas@apache.org">Nicolas De Loof</a>
 */
public abstract class AbstractQueryParser
{

    /** Cache allready parsed queries */
    private ConcurrentMap<String, PersistenceQuery> cache = new ConcurrentHashMap<String, PersistenceQuery>();

    public final PersistenceQuery parse( Class entityClass, Aggregate aggregate, String criteria, Class[] types )
    {
        String key =
            new StringBuilder( entityClass.getSimpleName() )
                .append( ":" ).append( aggregate )
                .append( ":" ).append( criteria )
                .toString();
        PersistenceQuery query = cache.get( key );
        if ( query == null )
        {
            query = doParse( entityClass, aggregate, criteria, types );
            PersistenceQuery previous = cache.putIfAbsent( key, query );
            if ( previous != null )
            {
                return previous;
            }
        }
        return query;
    }

    protected abstract PersistenceQuery doParse( Class entityClass, Aggregate aggregate, String criteria, Class[] types );

    public void setCustomQueries( Map<String, PersistenceQuery> queries )
    {
        cache.putAll( queries );
    }

}